#pragma once

#include <QMap>
#include <QObject>
#include <QDir>
#include "interfaces/InputOutputPlugin.h"
#include "interfaces/ProjectInputOutputPlugin.h"
#include "interfaces/DecoratePlugin.h"
#include "interfaces/FilterPlugin.h"
#include "interfaces/GuiPlugin.h"
#include "interfaces/EditPlugin.h"
#include "interfaces/DrawAreaPlugin.h"
#include "dynamic_common_global.h"

#ifdef DEBUG_PLUGINMANAGER
    #define DEBUGLINE 
#else
    #define DEBUGLINE if(false)
#endif

/// \brief This class provides the basic tools for managing all the plugins. It is used by both meshlab and meshlab server.
class DYNAMIC_COMMON_EXPORT PluginManager: public QObject{
    Q_OBJECT

public:
    /// Stores the loaded IO model plugins
    /// @todo necessary? just use the values of the hash map 
    QMap<QString,InputOutputPlugin*> modelIOPlugins;
    /// Extension (lowercase) => IO model plugin
    QHash<QString,InputOutputPlugin*> modelExtensionToPlugin;
    
    /// Stores the loaded IO project plugins
    /// @todo necessary? just use the values of the hash map 
    QVector<ProjectInputOutputPlugin*> projectIOPlugins;   
    /// Extension (lowercase) => IO project plugin
    QHash<QString,ProjectInputOutputPlugin*> projectExtensionToPlugin;

    /// @{ Store the loaded plugins by name
        QMap<QString,FilterPlugin*> filterPlugins;
        QMap<QString,GuiPlugin*> guiPlugins;
        QMap<QString,DecoratePlugin*> decoratePlugins;    
        QMap<QString,EditPlugin*> editPlugins;
        QMap<QString,DrawAreaPlugin*> drawAreaPlugins;
    /// @}
public:
    PluginManager();

    /// Directory where plugins are found
    QDir pluginsDir;    
    static QString getPluginDirPath();
    static QString getBaseDirPath();
    
    /// Assemble string for file open/save filters
    QString getFilterStrings();
    
private:
    /// Searches pluginsDir for plugins
    void loadPlugins();

/// Set of helper functions
private:
    bool load_InputOutputPlugin(QObject* plugin);
    bool load_ProjectInputOutputPlugin(QObject* plugin);
    bool load_FilterPlugin(QObject* plugin);
    bool load_EditPlugin(QObject* plugin);
    bool load_DecoratePlugin(QObject* plugin);    
    bool load_GuiPlugin(QObject* _plugin);
    bool load_DrawAreaPlugin(QObject* _plugin);
};
